<template>
  <div class="login-page">
    <div class="login-wrap">
      <div class="login-form">
        <h4>用户登录</h4>
        <el-form ref="formRef" :model="form" :rules="rules" label-width="80px;">
          <el-form-item prop="username">
            <el-input v-model="form.username" v-trim clearable placeholder="请输入账号" @keyup.enter="handleLogin">
              <!--              <i slot="prefix" class="el-input__icon el-icon-user"></i>-->
            </el-input>
          </el-form-item>
          <el-form-item prop="password">
            <el-input v-model="form.password" v-trim clearable placeholder="请输入密码" type="password"
                      @keyup.enter="handleLogin">
              <!--              <i slot="prefix" class="el-input__icon el-icon-lock"></i>-->
            </el-input>
          </el-form-item>
          <el-form-item prop="verification">
            <div style="display: flex;width: 100%;">
              <el-input
                v-model="form.verification"
                clearable
                v-trim
                placeholder="请输入验证码"
                @keyup.enter="handleLogin">
                <!--                <i slot="prefix" class="el-input__icon el-icon-key"></i>-->
              </el-input>
            </div>
          </el-form-item>
          <el-form-item>
            <div style="display: flex;width: 100%; align-items: center;">
              <el-image :src="verificationImageSrc" style="width: 180px;height: 60px;"
                        v-loading="getImageLoading"></el-image>
              <el-button text @click="getVerificationImage">
                换一张
                <i class="el-icon-refresh" style="font-size: 20px;margin-left: 10px;"></i>
              </el-button>
            </div>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" size="large" :loading="loginLoading" style="width: 100%;" @click="handleLogin">
              登录
            </el-button>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" size="large" :loading="loginLoading" style="width: 100%;"
                       @click="handleMockLogin">mock登录
            </el-button>
          </el-form-item>
        </el-form>
        <div class="forget-password" @click="handleForgetPassword">忘记密码？</div>
      </div>
    </div>
    <forget-password-dialog v-model:visible="forgetPasswordVisible"></forget-password-dialog>
  </div>
</template>

<script setup>
import { onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { randomNum, awaitWrap, readBlob } from '@/utils'
import { encryptSHA256, getMD5String } from '@/utils/encryption'
import { SUCCESS_CODE } from '@/constants'
import { getValidateCodeImage, userLogin } from '@/api/login'
import { ElMessage, ElMessageBox } from 'element-plus'
import { PAGE_CODE_LIST, MENU_LISTS } from '@/constants/mock-login-data'
import ForgetPasswordDialog from '@/views/login/ForgetPasswordDialog.vue'

// ---------------------路由-------------------
const router = useRouter()

// ---------------------store-------------------
const store = useStore()

// ---------------------form组件实例-------------------
const formRef = ref()
// ---------------------初始化相关-------------------
onMounted(() => {
  getVerificationImage()
})

// ---------------------登录form表单相关-------------------
// 初始表单
const initForm = {
  username: '',
  password: '',
  verification: ''
}
// form的响应式
const form = reactive({ ...initForm })
// 规则
const rules = reactive({
  username: [{ required: true, message: '请输入账号', trigger: 'blur' }],
  password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
  verification: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
})

// ---------------------获取验证图片相关-------------------
const getImageLoading = ref(false) // 图片获取loading
const verificationImageSrc = ref('')
const uuid = ref('')
// 设置uuid
const getUuid = () => {
  uuid.value = new Date().getTime() + randomNum(6)
}
// 初始化获取图片验证
const getVerificationImage = async () => {
  getUuid()
  getImageLoading.value = true
  const { res } = await awaitWrap(getValidateCodeImage(uuid.value))
  if (res) {
    try {
      await readBlob(res.data)
      verificationImageSrc.value = window.URL.createObjectURL(new Blob([res.data]))
    } catch (e) {
      ElMessage.error('验证码获取失败')
    }
  }
  getImageLoading.value = false
}

// ---------------------登录相关-------------------
const loginLoading = ref(false)
// 设置登录参数
const setLoginParams = () => {
  return {
    accountName: form.username,
    password: encryptSHA256(form.password),
    code: form.verification,
    uuid: uuid.value
  }
}
// 检验表单提交
const validateFormInput = () => {
  return new Promise(resolve => {
    formRef.value.validate(valid => {
      if (valid) {
        resolve()
      }
    })
  })
}
// 假登录
const handleMockLogin = async () => {
  store.dispatch('setLoginData', {
    userInfo: {
      name: '梅俊峰',
      id: '222'
    },
    token: '123',
    resources: {
      menuList: MENU_LISTS,
      permissionCodeList: PAGE_CODE_LIST
    }
  }).then(() => {
    router.push({ path: '/sample/list' })
  })
}
// 登录
const handleLogin = async () => {
  await validateFormInput()
  const params = setLoginParams()
  loginLoading.value = true
  const { res } = await awaitWrap(userLogin(params))
  if (res?.statusCode === SUCCESS_CODE) {
    const data = res.data || {}
    const userResources = data.fresources || []
    if (userResources.length === 0) {
      ElMessageBox.alert('该账号没有绑定任何权限，无法进行操作，请联系管理员处理。', '出现错误', {
        confirmButtonText: '确定',
        type: 'error',
        dangerouslyUseHTMLString: true
      })
    } else {
      const path = await saveUserBaseInfo(data)
      router.push({ path })
    }
  } else {
    getVerificationImage()
  }
  loginLoading.value = false
}
// 保存用户信息
const saveUserBaseInfo = data => {
  return new Promise(resolve => {
    const u = data.fuser
    const userInfo = {
      id: u.fid,
      phone: u.fphone,
      name: u.faccountName,
      // region: u.fregion,
      realName: u.frealName
    }
    const resources = dealResource(data.fresources || [])
    store.dispatch('setLoginData', {
      userInfo,
      token: data.ftoken,
      resources
    }).then(() => {
      resolve(resources.pathList[0])
    })
  })
}
// ---------------------登录后返回的数据进行处理-------------------
// 处理登录资源数据
const dealResource = (resources) => {
  const menuList = []
  const btnList = []
  const pathList = []
  const permissionCodeList = []
  iterateDecorateResource(menuList, btnList, pathList, permissionCodeList, resources)
  return {
    menuList,
    btnList,
    pathList,
    permissionCodeList
  }
}
const iterateDecorateResource = (menuList, componentList, pathList, permissionCodeList, source = []) => {
  source.forEach((v, i) => {
    if (v.ftype === 'MODULE' || v.ftype === 'SUB-MODULE' || v.ftype === 'PAGE') {
      const item = {
        title: v.fname,
        url: v.furl,
        icon: v.ficon,
        children: []
      }
      if (v.fchildren && v.fchildren.length > 0) {
        iterateDecorateResource(item.children, componentList, pathList, permissionCodeList, v.fchildren)
      }
      menuList.push(item)
      permissionCodeList.push(v.fcode)
      if (v.furl) pathList.push(v.furl)
    } else if (v.ftype === 'COMPONENT') {
      componentList.push(v.fcode)
      permissionCodeList.push(v.fcode)
      if (v.fchildren && v.fchildren.length > 0) {
        iterateDecorateResource(null, componentList, pathList, permissionCodeList, v.fchildren)
      }
    }
  })
}

// ---------------------忘记密码-------------------
const forgetPasswordVisible = ref(false)
const handleForgetPassword = () => {
  forgetPasswordVisible.value = true
}
</script>

<style scoped lang="scss">
.login-page {
  width: var(--zoomVw);
  height: var(--zoomVh);
  overflow: auto;
  display: flex;
  --color: #E1E1E1;
  background-color: #F3F3F3;
  background-image: linear-gradient(0deg, transparent 24%, var(--color) 25%, var(--color) 26%, transparent 27%, transparent 74%, var(--color) 75%, var(--color) 76%, transparent 77%, transparent),
  linear-gradient(90deg, transparent 24%, var(--color) 25%, var(--color) 26%, transparent 27%, transparent 74%, var(--color) 75%, var(--color) 76%, transparent 77%, transparent);
  background-size: 55px 55px;

  .login-wrap {
    margin: auto;
    display: flex;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    border-radius: 10px;
    overflow: hidden;
    $child-padding: 20px 40px; // 子元素padding
    .login-form {
      width: 300px;
      background: #fff;
      padding: $child-padding;

      h4 {
        line-height: 80px;
        font-size: 20px;
        font-weight: 600;
        letter-spacing: 3px;
      }

      .el-input__icon {
        font-size: 20px;
      }

      .forget-password {
        font-size: 13px;
        cursor: pointer;
        color: #909399;
        text-align: right;
      }
    }
  }
}
</style>
